// core 核心
const {
    MongoClient
} = require('mongodb');
const {
    db
} = require('../config')


// connect函数帮助我们连接 和关闭数据库， 并且返回操作数据库的结果
// collectionName 集合名称   callback操作数据库业务的回调函数   dbName 数据库名称  url： 数据库的链接地址
async function connect(collectionName, callback, dbName = db.name, url = db.url) {
    // 获取客户端实例
    const client = new MongoClient(url)

    // 通过客户端 连接上mongodb
    // client.connect方法 返回是一个promise对象
    try {
        await client.connect()
        // 获取db实例
        const db = client.db(dbName);
        // 获取集合实例
        const collection = db.collection(collectionName)

        //  调用回调函数 callback， callback中写得就是操作数据库的各种业务代码，需要我们把collection集合实例传给回调函数中进行使用
        const result = await callback(collection)

        // 获取了操作数据库的结果之后，我们关闭连接
        await client.close()

        //  把最终的结果进行返回（请注意 aysnc函数返回的结果都是promise对象）
        return result

    } catch (e) {
        //  console.log('出错了')
        //  console.log(e)
        // 关闭连接
        await client.close()

        //  因为 async函数 必须返回promise对象， 出现了错误的情况的话， 返回 状态为rejected的promise对象
        return Promise.reject(e)
    }

}

// connect('user', collection => {
//     return collection.find().toArray() // 都是返回的 promise对象
// }).then(data => console.log(data))

// connect('user', collection => {
//     return collection.deleteOne() // deleteOne返回的是promise对象
// })

// 再封装一些数据库的通用方法 例如findOne
exports.findOne = function (collectionName, query = {}) {
    return connect(collectionName, collection => {
        return collection.findOne(query)
    })
}

// 
exports.findMany = function (collectionName, query = {}, limit = 5, skip = 0, sort = {
    _id: -1
}) {
    return connect(collectionName, collection => {
        return collection.find(query).limit(limit).skip(skip).sort(sort).toArray()
    })
}

exports.insertOne = function (collectionName, data) {
    return connect(collectionName, collection => {
        return collection.insertOne(data)
    })
}

exports.deleteOne = function (collectionName, query) {
    return connect(collectionName, collection => {
        return collection.deleteOne(query)
    })
}

exports.updateOne = (collectionName, query, data) => connect(collectionName, collection => collection.updateOne(query, data))

// 用来查询文档的数量
exports.count = (collectionName, query = {}) => connect(collectionName, collection => collection.count(query))